<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>


  <!-- 原型链继承
          缺点：原型中引用值类型会在 所有实例间 共享
                子类型实例化时 不能 给父类型 传参
  -->
  <script>
    function Father(){
      this.name = '父'
    }
    Father.prototype.sayName = function(){
      console.log(this.name) 
    }
    function Son(){
      this.name = '子'
    }
    Son.prototype = new Father()
    let son = new Son()
    son.sayName()
  </script>

  <!-- 盗用构造函数
          缺点：必须在构造函数中定义方法，每次创建子类实例都会创建一遍方法，函数不能重用
  -->
  <script>
    function Father(name){
      this.name = name
      this.arr = []
      this.sayName = function(){
        console.log(this.name)
      }
    }
    function Son(name){
      Father.call(this,name) //盗用父类构造函数
    }
    let father = new Father("父")
    console.log(father)
    let son = new Son("子")
    console.log(son)
    console.log(father.arr === son.arr) //false
    console.log(father.sayName === son.sayName) //false
  </script>

  <!-- 组合继承（原型链和盗用构造函数组合）
         弥补了两种的不足
         缺点：效率问题，父类构造函数会被调用两次
  -->
  <script>
    function Father(name){
      console.log("调用父类构造函数")  //调用两次
      this.name = name
    }
    Father.prototype.sayName = function(){
      console.log(this.name)
    }
    function Son(name){
      Father.call(this,name) //盗用父类构造函数，调用一次父类构造函数
    }

    Son.prototype = new Father()  //原型链方式 ，调用一次父类构造函数
    Son.prototype.constructor = Son

    let son = new Son("子") 
    son.sayName()
    console.log(son)
    console.log(Father.prototype.constructor)
    console.log(Son.prototype.constructor)
  </script>

    
  <!-- 寄生组合式继承
        解决组合式缺点
  -->
  <script>
    function Father(name){
      this.name = name
    }
    Father.prototype.sayName = function(name){
      console.log(this.name)
    }
    function Son(name,age){
      Father.call(this,name)
      this.age = age
    }
    Son.prototype = Object(Father.prototype) //寄生
    Son.prototype.constructor = Son

    let chil = new Son("aa",12)
    console.log(chil)
  </script>

  <!-- class实现继承 -->
  <script>
    class Father{
      constructor(name){
        this.name = name
      }
      sayName(){
        console.log(this.name)
      }
    }
    class Son extends Father{
      constructor(name){
        super(name)
      }
    }
    let son = new Son("子")
    son.sayName()
  </script>
</body>
</html>